﻿using System.Diagnostics;
using System.Reflection;
using OnDash.Windowing.GraphicsLibraryFramework;

namespace OnDash.Windowing.Desktop;

public static class GlfwProvider
{
    private static readonly GlfwCallbacks.ErrorCallback ErrorCallback =
        (errorCode, description) => throw new GlfwException(description, errorCode);

    private static Thread _mainThread;

    private static bool Initialized = false;
    public static bool IsOnMainThread => CheckForMainThread == false || _mainThread == Thread.CurrentThread;

    public static bool CheckForMainThread { get; set; } = true;

    public static void EnsureInitialized()
    {
        if (CheckForMainThread)
        {
            if (_mainThread == null!)
            {
                if (Thread.CurrentThread.IsBackground == false &&
                    Thread.CurrentThread.IsThreadPoolThread == false &&
                    Thread.CurrentThread.IsAlive)
                {
                    var correctEntryMethod = Assembly.GetEntryAssembly()!.EntryPoint;
                    var trace = new StackTrace();
                    var frames = trace.GetFrames();
                    for (var i = frames.Length - 1; i >= 0; i--)
                    {
                        var method = frames[i].GetMethod();
                        if (correctEntryMethod != method) continue;
                        _mainThread = Thread.CurrentThread;
                        break;
                    }
                }
            }

            if (_mainThread?.ManagedThreadId != Environment.CurrentManagedThreadId)
            {
                throw new GlfwException("GLFW can only be called from the main thread!");
            }
        }

        if (Initialized) return;
        Glfw.Init();
        Glfw.SetErrorCallback(ErrorCallback);
        Initialized = true;
    }
}